package de.kuttenmann.jflake;
public class Sphere
{
	private final Vector3D center;
	private final double radius;

	public Sphere(Vector3D center, double radius)
	{
		this.center = center;
		this.radius = radius;
	}

	/**
	 * Intersects this sphere with the given ray and returns the distance to the intersection point
	 * if any. Otherwise, it returns {@link Hit#INFINITY}.
	 * 
	 * @param ray The ray to intersect this sphere with
	 * @return The distance to the intersection point or {@link Hit#INFINITY} if there is no hit
	 */
	public double intersect(Ray ray)
	{
		Vector3D distance = this.center.sub(ray.getOrigin()); 
		double orientation = ray.getDirection().dot(distance);
		double discriminant = orientation * orientation - distance.dot(distance) + this.radius * this.radius;

		if(discriminant < 0.0)
		{
			return Hit.INFINITY; /*branch away from the square root*/
		}
		double position = Math.sqrt(discriminant);
		double hit1 = orientation + position;
		double hit2 = orientation - position;
		if(hit1 < 0.0)
		{
			return Hit.INFINITY;
		}
		else
		{
			return (hit2 > 0.0 ? hit2 : hit1);
		}
	}

	public Hit calculateHit(Ray ray, double distance)
	{
		Vector3D intersection = ray.getOrigin().add(ray.getDirection().scale(distance));
		Vector3D normal = intersection.sub(this.center).scale(1.0 / this.radius);
		return new Hit(normal, distance);
	}
}
